
#include <vector>
#include <memory>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
using std::unique_ptr;

class Point
{
public:
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {   cout << "Point(int,int)" << endl;    }

    ~Point()
    {   cout << "~Point()" << endl; }  

    void print() const 
    {
        cout << "(" << _ix
             << "," << _iy
             << ")" << endl;
    }

private:
    int _ix;
    int _iy;
};

//当局部对象up2即将被销毁时，调用的是
//unique_ptr的移动构造函数，没有调用拷贝构造函数
unique_ptr<Point> getValue()
{
    unique_ptr<Point> up2(new Point(10, 11));
    up2->print();
    return up2;
}

void test0()
{
    Point * pt = new Point(1, 2);
    unique_ptr<Point> up(pt);
    cout << "up'get():" << up.get() << endl;
    cout << "pt:" << pt << endl;
    up->print();
    (*up).print();

    cout << endl;

    //unique_ptr不能进行复制或者赋值
    //unique_ptr<Point> up2 = up; //error

    //可以表达移动语义
    //getValue的返回值是一个右值,所以可以正常运行
    //&getValue();//error 右值
    unique_ptr<Point> up2 = getValue();
    cout << "*up2.print():" ;
    (*up2).print();

    //unique_ptr可以作为容器的元素
    vector<unique_ptr<Point>> numbers;
    //up2是一个左值,这里要调用拷贝构造函数
    //numbers.push_back(up2);//error 
    //
    //当使用了std::move函数之后，就会将up2所托管的
    //对象转移到容器中
    numbers.push_back(std::move(up2));

    //转移完毕之后，原来的up2中就只剩下一个空指针了
    //如果再去执行，就会报段错误
    //up2->print();//error
    cout << "111" << endl;
    //如果重新托管一个新对象，就可以正常使用了
    up2.reset(new Point(33, 44));
    up2->print();

    up2 = std::move(up);
}


int main()
{
    test0();
    return 0;
}

